package com.example.redis_canal_mysql_demo.geoService;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.*;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.awt.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author LiHaoyang
 * @date 2023/4/26  19:34
 **/
@Service
@Slf4j
public class GeoService {

    private static final String CITY="city";

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 添加经纬度坐标
     * @return
     */
    public String geoAdd(){
        Map<String, Point> map = new HashMap<>();
        map.put("天安门",new Point(116.403963,39.915119));
        map.put("故宫",new Point(116.403414,39.924091));
        map.put("长城",new Point(116.024067,40.362639));

        redisTemplate.opsForGeo().add(CITY,map);
        return map.toString();
    }

    /**
     * 获取经纬度坐标
     * @param member 目标地区
     * @return
     */
    public Point position(String member) {
        List<Point> position = redisTemplate.opsForGeo().position(CITY, member);
        return position.get(0);
    }

    /**
     * geohash生成base32编码值
     * @param member 目标
     * @return
     */
    public String hash(String member) {
        List<String> hash = redisTemplate.opsForGeo().hash(CITY, member);

        return hash.get(0);
    }

    /**
     * 两个地区之间的距离
     * @param member1 第一个地区
     * @param member2 第二个地区
     * @return
     */
    public Distance distance(String member1, String member2) {
        Distance distance = redisTemplate.opsForGeo().distance(CITY, member1, member2, RedisGeoCommands.DistanceUnit.KILOMETERS);
        return distance;
    }

    /**
     * 以当前定位为圆心查找指定半径以内的目标
     * @return
     */
    public GeoResults radiusByxy() {
        Circle circle = new Circle(116.418017, 39.914402, Metrics.KILOMETERS.getMultiplier());
        //找出多少个目标
        RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().sortDescending().limit(50);
        GeoResults<RedisGeoCommands.GeoLocation<String>> geoResults = redisTemplate.opsForGeo().radius(CITY, circle, args);
        return geoResults;
    }

    /**
     * 通过地方查找附近
     * @return
     */
    public GeoResults radiusMember() {
        String member = "天安门";
        RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().sortAscending().limit(10);
        Distance distance = new Distance(10, Metrics.KILOMETERS);

        GeoResults<RedisGeoCommands.GeoLocation<String>> radius = redisTemplate.opsForGeo().radius(CITY, member, distance, args);
        return radius;
    }
}
